/*
 * @Description: 主组件
 * @Author: mofish
 * @Date: 2022-05-27
 * @LastEditTime: 2022-05-27
 * @LastEditors: mofish
 */
import React from 'react'
import { Navigate, RouteObject } from 'react-router-dom'
import Guard from './guard'
import { EasyRoutePropsType, ReactElementType, RoutesItemType, MetaType, FunctionalImportType, 
  BeforeRouteEnterType } from '../../types'

class EasyCore {
  routes
  beforeRouteEnter
  loading

  constructor (option: EasyRoutePropsType) {
    this.routes = option.routes || []
    this.beforeRouteEnter = option.beforeRouteEnter
    this.loading = option.loading || (<div></div>)
  }

  /**
   * @description: 路由配置列表数据转换
   * @param {string} redirect 要重定向的路由路径
   * @param {function} component 函数形式import懒加载组件
   * @param {object} meta 自定义字段
   */
  transformRoutes (routeList = this.routes) {
    const list: RouteObject[] = []
    routeList.forEach(route => {
      const obj = { ...route }
      if (obj.path === undefined) {
        return
      }
      if (obj.redirect) {
        obj.element = <Navigate to={obj.redirect} replace={true}/>
      } else if (obj.component) {
        obj.element = this.lazyLoad(obj.component, obj.meta || {})
      }
      if (obj.children) {
        obj.children = this.transformRoutes(obj.children)
      }
      // 添加路由守卫
      obj.element = this.routeGuard(obj, this.beforeRouteEnter)
      delete obj.redirect
      delete obj.component
      delete obj.meta
      list.push(obj)
    })
    return list
  }

  /**
   * @description: 路由懒加载
   */
  lazyLoad(importFn: FunctionalImportType, meta: MetaType) {
    const Element = React.lazy(importFn)
    const lazyElement = (
      <React.Suspense fallback={this.loading}>
        <Element _meta={meta}/>
      </React.Suspense>
    )
    return lazyElement
  }

  // 路由守卫
  routeGuard(route: RoutesItemType, beforeRouteEnter: BeforeRouteEnterType | undefined) {
    const { element, meta } = route
    return (
      <Guard
        element={element as ReactElementType}
        meta={meta || {}}
        beforeRouteEnter={beforeRouteEnter}
      />
    )
  }
}

export default EasyCore